#include "ParserInterface.h"
#include <string.h>

ParserInterface::ParserInterface()
{
    //ctor
}

ParserInterface::~ParserInterface()
{
    //dtor
}

void ParserInterface::setInputString (const char* input, int len)
{
    mInput = input;
    mLen   = len;
    mCurr  = -1;
}

void ParserInterface::setInputString (const std::string& input)
{
    setInputString (input.c_str(), input.length() );
}

void ParserInterface::prolog()
{
    getChar();
}

void ParserInterface::epilog()
{

}

void ParserInterface::rewind_stream()
{
    mCurr = -1;
    prolog();
}

void ParserInterface::getChar()
{
    ++mCurr;
}

bool ParserInterface::isEqual(char ch) const
{
    return mInput[mCurr] == ch;
}

bool ParserInterface::isEOF() const
{
    return mCurr >= mLen;
}

bool ParserInterface::isDot () const
{
    return isEqual('.');
}

bool ParserInterface::isUnderscore () const
{
    return isEqual('_');
}

bool ParserInterface::isLetter() const
{
    return isalpha (mInput[mCurr]) != 0;
}

bool ParserInterface::isLetterOrDigit() const
{
    return isalnum (mInput[mCurr]) != 0;
}

bool ParserInterface::isWhitespace() const
{
    return isspace (mInput[mCurr]) != 0;
}

void ParserInterface::skipWhite()
{
    while (!isEOF () && isWhitespace() ) {
        getChar ();
    }
}

void ParserInterface::skipToChar (char ch)
{
    while (!isEOF () && !isEqual(ch)) {
		getChar ();
	}
}

void ParserInterface::skipToString (const std::string& str)
{
    if (!isEOF() ) {
        char* tmpS = strstr (mInput + mCurr, str.c_str());
        if (tmpS) {
            mCurr = (tmpS - mInput);
        }
    }
}

bool ParserInterface::match (char ch)
{
    if (!isEOF () && isEqual (ch) ) {
        getChar ();
        skipWhite ();
        return true;
    } else {
        return false;
    }
}

bool ParserInterface::matchString (const std::string& str)
{
    if (mLen - mCurr >= str.size () ) {
        for (int i = 0; i < str.size (); ++i) {
            if (mInput[mCurr] == str[i]) {
                getChar ();
            } else {
                return false;
            }
        }
        skipWhite ();
        return true;
    }
    else {
        return false;
    }
}

void ParserInterface::expected (const std::string& str)
{
    fprintf(stdout, "%s\n", str.c_str());
}

std::string ParserInterface::name()
{
    std::string s_name;
    while (!isEOF () && (isLetterOrDigit() || isUnderscore() ) ) {
        s_name += mInput[mCurr];
        getChar ();
    }

    skipWhite ();
    return s_name;
}

const char* ParserInterface::current()
{
    return mInput + mCurr;
}

int ParserInterface::remainCharsNum() const
{
    return mLen - mCurr;
}

std::string ParserInterface::trimLeft_const(std::string str)
{
    trimLeft_mutable(str);
    return str;
}

void ParserInterface::trimLeft_mutable(std::string& str)
{
    for (auto iter = str.begin(); iter != str.end(); iter++) {
        if (!isspace(*iter)) {
            str.erase(str.begin(), iter);
            return;
        }
    }
}

std::string ParserInterface::trimRight_const(std::string str)
{
    trimRight_mutable(str);
    return str;
}

void ParserInterface::trimRight_mutable(std::string& str)
{
    for (auto riter = str.rbegin(); riter != str.rend(); riter++) {
        if (!isspace(*riter)) {
            str.erase(riter.base(), str.end());
            return;
        }
    }
}

std::string ParserInterface::trim_const(std::string str)
{
    trim_mutable(str);
    return str;
}

void ParserInterface::trim_mutable(std::string& str)
{
    trimLeft_mutable(str);
    trimRight_mutable(str);
}
